package com.zb.service.imp.middleware;

import com.alibaba.fastjson.JSON;
import com.zb.dao.ext.dic.OmsPubParamDao;
import com.zb.service.middleware.AnalysisService;
import com.zb.service.sys.BillService;
import com.zb.service.sys.ChargerChargeDirectRecordService;
import com.zb.service.sys.ChargerService;
import com.zb.service.sys.OmsDicForwardSrvInfoService;
import com.zb.tcp.rpc.os.OrderRpcClient;
import com.zb.util.RedisClient;
import com.zb.util.StringUtil;
import com.zb.vo.oms.BatteryInfoUploadVO;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.Jedis;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

//import com.dz.order.vo.OrderBaseData;

//本接口只做数据解析，不做数据接收  TODO dao 改 service
//只用protocol_version
//chargerId:桩地址  port  source_ip source_port data  protocol_type  protocol_version 
@Service @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class Ev3c2AnalysisServiceImpl implements AnalysisService{

	private Log log = LogFactory.getLog(Ev3c2AnalysisServiceImpl.class);

//	@Resource
//	RedisClient RedisClient;
//	@Resource
//	OmsChargerDao omsChargerDao;
	@Resource
	ChargerService chargerService;
//	@Resource
//	OmsChargerStateDirectDao omsChargerStateDirectDao;
//	@Resource
//	OmsChargerStateAlternateDao omsChargerStateAlternateDao;
//	@Resource
//	OmsChargerBespeakBillRecordDao omsChargerBespeakBillRecordDao;
	@Resource
	BillService billService;
//	@Resource
//	OmsChargerChargeBillRecordDao omsChargerChargeBillRecordDao;
	@Resource
	OmsPubParamDao omsPubParamDao;
//	@Resource
//	OmsChargerChargeDirectRecordDao omsChargerChargeDirectRecordDao;
	@Resource
	ChargerChargeDirectRecordService chargerChargeDirectRecordService;
//	@Resource
//	OrderRpcClient orderRpcClient;
//	@Resource
//	OmsDicForwardSrvInfoDao omsDicForwardSrvInfoDao;
	@Resource
	OmsDicForwardSrvInfoService omsDicForwardSrvInfoService;
	
//	String ev3c_msg,ev3c_msgBody,ev3c_msgHeader,ev3c_frameCode,chargerId,protocol_version;
	//6.1 注册 
	@Override
	public Map<String, String> chargerRegister(Map<String, String> map) {
		//报文头解析
		map = getEv3c2MsgHeaderByMiddleBegin(map);
		log.info(map);
		// 报文体解析
		String chargerMsgBody = map.get("chargerMsgBody");
		String fac_login_name = chargerMsgBody.substring(0, 8); //注册账号  00005024  厂商表中检查
		String fac_password = chargerMsgBody.substring(8, 16); //注册密码      21968502    
		String port_quantity_bin = chargerMsgBody.substring(16, 18); //BIN	1	此充电桩的充电口的总数量   
		int  port_quantity_int =StringUtil.int16to10ByParam(port_quantity_bin, 1);
		String port_quantity =String.valueOf(port_quantity_int);
		String ev_fac_type = chargerMsgBody.substring(18, 20); //设备一级类型  01      高4位: 0 壁挂式   1 立式   2内嵌式   F 其它  低4位：     0  单枪单充    1  双枪双充2  双枪单充 ……
//		String ev_fac_type1 =ev_fac_type.substring(0, 1);//设备一级类型
		String charge_port_quantity = ev_fac_type.substring(1, 2);
		String is_parallel_charge ="0";
		if(charge_port_quantity.equals("1")){
			is_parallel_charge = "1";
		}
		log.info("register");
		String ev_fac_type2 = chargerMsgBody.substring(20, 22); //设备二级类型  00  
		String software_version = chargerMsgBody.substring(22, 26); //设备SN  16位                     
		String protocol_version = chargerMsgBody.substring(26, 30); //设备SN  16位       
		String ev_sn = chargerMsgBody.substring(30, 70); //设备SN  16位        16*2 =32


		log.info("register after read");
		map.put("fac_login_name", fac_login_name);
		map.put("fac_password", fac_password);
		map.put("port_quantity", port_quantity);
		map.put("is_parallel_charge", is_parallel_charge);
		map.put("ev_fac_type1", ev_fac_type);
		map.put("ev_fac_type2", ev_fac_type2);
		map.put("software_version", software_version);
		if(map.get("protocol_type")==null){
			map.put("protocol_type","0201");
		}
		if(map.get("protocol_version")==null){
			map.put("protocol_version",protocol_version);
		}
		map.put("ev_sn", ev_sn);
		return map;
	}
	
	@Override
	public Map<String, String> login(String str) {
		Map<String, String> map = StringUtil.ev3cString2JSONObject(str);
		String data = map.get("data");
		//报文体
		String fac_login_name = data.substring(50, 58); //注册账号  00005024  厂商表中检查
		String fac_password = data.substring(58, 66); //注册密码      21968502    
		String ev_fac_type1 = data.substring(66, 68); //设备一级类型  01      
		String ev_fac_type2 = data.substring(68, 70); //设备二级类型  00     
		String ev_sn = data.substring(70, 86); //设备SN  16位                          
		String ev_gps = data.substring(86, 102); //GPS坐标   16位   00..00
		map.put("fac_login_name", fac_login_name);
		map.put("fac_password", fac_password);
		map.put("ev_fac_type1", ev_fac_type1);
		map.put("ev_fac_type2", ev_fac_type2);
		map.put("ev_sn", ev_sn);
		map.put("ev_gps", ev_gps);
		return map;
	}

	@Override
	public Map<String, String> logout(String str) {
		//解析报文头
		Map<String, String> map= StringUtil.ev3cString2JSONObject(str);
		//报文体无
		return map;
	}

	public String subString(String str,int length){
		return str.substring(0, length);
	}
	public String substringStr(String str,int length){
		return str.substring(length, str.length() - length);
	}
	static final int msgBody_length = 4 ;
	static final int chargerId_length = 16 ;
	static final int startType_length = 2 ;
	static final int frameType_length = 2 ;
	static final int chargerType_length = 1 ;
	static final int portNo_length = 1 ;
	static final int communicationNo_length = 4 ;
	static final int encryption_length = 2 ;
	static final int chargerSerialNumber_length = 18 ;
	static final int msgResponseCode_length = 6 ;
	static final int omsSerialNumber_length = 18 ;
	
	//电桩上传：25*2=50,主动上报报文头与1.X版本一致    服务器 返回报文头 为 37*2 =74
	//服务器主动下发报文头：23*2 = 46 ，电桩回复报文头 35*2 =70
	//Ev3c 2.0协议从电桩发起的请求报文头解析
	public Map<String,String> getEv3c2MsgHeaderByMiddleBegin(Map<String,String> map) {
		log.info("getEv3c2MsgHeaderByMiddleBegin");
		log.info(map);
		//以下是报文头 ,报文头长度为50
		String data = map.get("data");
		if ((data == null) || (data.length() < 50)) {
			map.put("errorMsg", "data length < 50");
			return map;
		}
		int msgBodyLength = data.length() - 50;
		String msgBody_bin = data.substring(2, 6);
		int msgBody_int = (int)StringUtil.float16to10ByParamDesc(msgBody_bin, 1);
		if(msgBody_int*2 != msgBodyLength){
			map.put("errorMsg", "data  msgBody	length not equal msgHeader describe");
			return map;
		}
		if(map.get("chargerId")==null){
			map.put("errorMsg", "chargerId not in json from middle");
			return map;
		}
		if(map.get("chargerId").length()!=16){
			map.put("errorMsg", "chargerId length not right");
			return map;
		}
		String subData = data;
//		private static int CODE_OFFSET=2;
		map.put("data", data);
		
//		map.put("startType", subData.substring(0, 2));// 启动字符68 code_type
////		map.put("msgBodylength",  data.substring(2, 6));// 报文长度001E
//		map.put("frameType", data.substring(6, 8));// 0x00:未注册 0x01:已注册
//		map.put("chargerType", data.substring(24, 25));// 0：交流桩   1：直流桩  F：其它
//		map.put("portNo", data.substring(25, 26));// 0：电桩的所有充电口  1: 表示第一个充电口；2：表示第二个充电口；
//		map.put("communicationNo", data.substring(26, 30));//oms_operation_sp_list[充电运营服务商表] communication_no 运营商通讯编号,电桩为0001
//		map.put("encryption", data.substring(30, 32));//加密方式 0x00 不加密码  0x01 DES 0x02 3DES      0x03 AES
//		map.put("chargerSerialNumber", data.substring(32, 50));//电桩流水号
//		//格式为:YYYY-MM-DD-HH-MI-SS加上四位序号 例如：0x20 0x15 0x05 0x10 0x21 0x45 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号（同一时刻自增）
//		map.put("chargerMsgBody", data.substring(50));//电桩上传报文的报文体
		map.put("startType", subData.substring(0, startType_length));// 启动字符68 code_type
		subData = subData.substring(startType_length);
		subData = subData.substring(msgBody_length);
//		map.put("msgBodylength",  data.substring(2, 6));// 报文长度001E
		map.put("frameType", subData.substring(0, 8));// 0x00:未注册 0x01:已注册
		subData = subData.substring(frameType_length);
		map.put("communicationNo", subData.substring(0, communicationNo_length));//oms_operation_sp_list[充电运营服务商表] communication_no 运营商通讯编号,电桩为0001
		subData = subData.substring(communicationNo_length);
		subData = subData.substring(chargerId_length);
		map.put("chargerType", subData.substring(0,chargerType_length));// 0：交流桩   1：直流桩  F：其它
		subData = subData.substring(chargerType_length);
		map.put("portNo", subData.substring(0, portNo_length));// 0：电桩的所有充电口  1: 表示第一个充电口；2：表示第二个充电口；
		subData = subData.substring(portNo_length);
		map.put("encryption", subData.substring(0 , encryption_length));//加密方式 0x00 不加密码  0x01 DES 0x02 3DES      0x03 AES
		subData = subData.substring(encryption_length);
		map.put("chargerSerialNumber", subData.substring(0 ,chargerSerialNumber_length));//电桩流水号
		subData = subData.substring(chargerSerialNumber_length);
		//格式为:YYYY-MM-DD-HH-MI-SS加上四位序号 例如：0x20 0x15 0x05 0x10 0x21 0x45 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号（同一时刻自增）
		map.put("chargerMsgBody", data.substring(50));//电桩上传报文的报文体
		log.info("after getEv3c2MsgHeaderByMiddleBegin");
		return map;
	}
	//Ev3c 2.0协议从OMS发起的报文，电桩返回的报文头解析
	public Map<String,String> getEv3c2MsgHeaderByMiddleReturn(Map<String,String> map) {
		//以下是报文头 ,报文头长度为70
		String data = map.get("data");
		if ((data == null) || (data.length() < 74)) {
			map.put("errorMsg", "data length < 70");
			return map;
		}
		int msgBodyLength = data.length() - 74;
		String msgBody_bin = data.substring(2, 6);
		int msgBody_int = (int)StringUtil.float16to10ByParamDesc(msgBody_bin, 1);
		if(msgBody_int*2 != msgBodyLength){
			map.put("errorMsg", "data  msgBody	length not equal msgHeader describe");
			return map;
		}
		if(map.get("chargerId")==null){
			map.put("errorMsg", "chargerId not in json from middle");
			return map;
		}
		if(map.get("chargerId").length()!=16){
			map.put("errorMsg", "chargerId length not right");
			return map;
		}
		
//		map.put("data", data);
//		map.put("startType", data.substring(0, 2));// 启动字符68 code_type
////		map.put("msgBodylength",  data.substring(2, 6));// 报文长度001E
//		map.put("frameType", data.substring(6, 8));// 0x00:未注册 0x01:已注册
//		map.put("chargerType", data.substring(24, 25));// 0：交流桩   1：直流桩  F：其它
//		map.put("portNo", data.substring(25, 26));// 0：电桩的所有充电口  1: 表示第一个充电口；2：表示第二个充电口；
//		map.put("msgResponseCode", data.substring(26, 32));// 响应码	BCD码	3	具体见响应码附录    00 00 00	正常
//		map.put("encryption", data.substring(32, 34));//加密方式 0x00 不加密码  0x01 DES 0x02 3DES      0x03 AES
//		map.put("omsSerialNumber", data.substring(34, 52));//原服务器请求流水号
//		map.put("chargerSerialNumber", data.substring(52, 70));//电桩流水号
//		//格式为:YYYY-MM-DD-HH-MI-SS加上四位序号 例如：0x20 0x15 0x05 0x10 0x21 0x45 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号（同一时刻自增）
//		map.put("chargerMsgBody", data.substring(70));//电桩上传报文的报文体
		String subData = data;
		map.put("startType", subData.substring(0, startType_length));// 启动字符68 code_type
		subData = subData.substring(startType_length);
		subData = subData.substring(msgBody_length);

		map.put("frameType", subData.substring(0, frameType_length));// 0x00:未注册 0x01:已注册
		subData = subData.substring(frameType_length);
		map.put("communicationNo", subData.substring(0, communicationNo_length));// //oms_operation_sp_list[充电运营服务商表] communication_no 运营商通讯编号,电桩为0001
		subData = subData.substring(communicationNo_length);
		subData = subData.substring(chargerId_length);
		map.put("chargerType", subData.substring(0,chargerType_length));// 0：交流桩   1：直流桩  F：其它
		subData = subData.substring(chargerType_length);
		map.put("portNo", subData.substring(0, portNo_length));// 0：电桩的所有充电口  1: 表示第一个充电口；2：表示第二个充电口；
		subData = subData.substring(portNo_length);
		map.put("msgResponseCode", subData.substring(0, msgResponseCode_length));// 响应码	BCD码	3	具体见响应码附录    00 00 00	正常
		subData = subData.substring(msgResponseCode_length);
		map.put("encryption", subData.substring(0 , encryption_length));//加密方式 0x00 不加密码  0x01 DES 0x02 3DES      0x03 AES
		subData = subData.substring(encryption_length);
		map.put("omsSerialNumber", subData.substring(0 , omsSerialNumber_length));//原服务器请求流水号
		subData = subData.substring(omsSerialNumber_length);
		map.put("chargerSerialNumber", subData.substring(0 ,chargerSerialNumber_length));//电桩流水号
		subData = subData.substring(chargerSerialNumber_length);
		map.put("chargerMsgBody", subData);//电桩上传报文的报文体
		return map;
	}

	////充电  电桩回复（0x53）
	@Override
	public Map<String, String> startChargeReturn(Map<String, String> map) {
		//报文头解析
		map = getEv3c2MsgHeaderByMiddleReturn(map);
		// 无报文体解析
		return map;
	}

	//关闭充电      电桩回复（0x54）
	@Override
	public Map<String, String> stopChargeReturn(Map<String, String> map) {

		//报文头解析
		map = getEv3c2MsgHeaderByMiddleReturn(map);
		// 无报文体解析
		
		return map;
	}

	//预约    电桩回复（0x51）
	@Override
	public Map<String, String> bespeakReturn(Map<String, String> map) {

		//报文头解析
		map = getEv3c2MsgHeaderByMiddleReturn(map);
		// 无报文体解析
		return map;
	}

	//预约取消    电桩回复（0x52）
	@Override
	public Map<String, String> cancelBespeakReturn(Map<String, String> map) {
		//报文头解析
		map = getEv3c2MsgHeaderByMiddleReturn(map);
		// 无报文体解析
		return map;
	}
	
	////重启电桩            电桩回复（0x56）
	@Override
	public Map<String, String> restartChargerReturn(Map<String, String> map) {
		//报文头解析
		map = getEv3c2MsgHeaderByMiddleReturn(map);
		// 无报文体解析
		return map;
	}

	@Override
	public Map<String, String> updateFirmwareReturn(Map<String, String> map) {
		
		return null;
	}

	@Override
	public Map<String, String> findHardwareServerIpReturn(Map<String, String> map) {
		
		return null;
	}

	//更改服务器地址    电桩回复（0x55）
	@Override
	public Map<String, String> setHardwareServerIpReturn(Map<String, String> map) {

		//报文头解析
		map = getEv3c2MsgHeaderByMiddleReturn(map);
		// 无报文体解析
		return map;		

	}

	@Override
	public Map<String, String> setTimeReturn(Map<String, String> map) {
		
		return null;
	}

	@Override
	public Map<String, String> findRateReturn(Map<String, String> map) {
		
		return null;
	}

	@Override
	public Map<String, String> setRateReturn(Map<String, String> map) {
		
		return null;
	}

	@Override
	public Map<String, String> setQrCodeReturn(Map<String, String> map) {
		
		return null;
	}

	@Override
	public Map<String, String> findWhiteListReturn(Map<String, String> map) {
		
		return null;
	}

	@Override
	public Map<String, String> setWhiteListReturn(Map<String, String> map) {
		
		return null;
	}

	// 查询/配置电桩参数      电桩回复（0xB1）
	@Override
	public Map<String, String> setParamReturn(Map<String, String> map) {
		//报文头解析
		map = getEv3c2MsgHeaderByMiddleReturn(map);
		// 报文体解析
		String chargerMsgBody = map.get("chargerMsgBody");

		String time_block_number1 = "";     //当日分配的总时间段数BIN
		int time_block_numberinit = 0;      //当日分配的总时间段数INT
		String time_block_number = "";		//当日分配的总时间段数String

		String execute_type = chargerMsgBody.substring(0, 2); //执行类型
		map.put("execute_type", execute_type);

		if(execute_type.equals("00")||execute_type.equals("03")){

		}else{
			String parameter_type = chargerMsgBody.substring(2, 4); //参数类型
			map.put("parameter_type", parameter_type);
			switch (parameter_type) {
			case "00":		//对时0x00
				String correcting_time = chargerMsgBody.substring(4, 18); //对时时间
				map.put("correcting_time", correcting_time);
				break;
			case "01":		//运营二维码	0x01
				String qr_code = chargerMsgBody.substring(4, 16); //运营二维码
				map.put("qr_code", qr_code);
				break;
			case "02":		//电费费率  0x02
				time_block_number1 = chargerMsgBody.substring(4, 6); //当日分配的总时间段数
				time_block_numberinit = StringUtil.int16to10ByParam(time_block_number1, 1);
				time_block_number = String.valueOf(time_block_numberinit);
				//这里涉及N个时间段的事件检测点和对应的费率，报文长度不确定。
				List<String> list_1 = new ArrayList<String>();//每个时间段的截止时间点
				List<String> list_2 = new ArrayList<String>();//每时间段的费率
				for(int i=0;i<time_block_numberinit;i++){
					String deadline_time = chargerMsgBody.substring( 6+(18*i),20+(18*i) );
					list_1.add(deadline_time);
					String time_rate = chargerMsgBody.substring( 20+(18*i),24+(18*i) );
					list_2.add(time_rate);
				}
				map.put("time_block_number", time_block_number);

				String key_1 = map.get("chargerId")+"0"+map.get("portNo")+"_time_block_1";
				String key_2 = map.get("chargerId")+"0"+map.get("portNo")+"_time_block_2";
				String key_3 = map.get("chargerId")+"0"+map.get("portNo")+"_time_block_3";
				RedisClient.putMap(key_1, map);
				RedisClient.putList(key_2, list_1);
				RedisClient.putList(key_3, list_2);
				break;
			case "03":		//服务费  0x03
				String charge_mode = chargerMsgBody.substring(4, 6); //计费方式
				String rate = chargerMsgBody.substring(6, 10); //费率
				time_block_number1 = chargerMsgBody.substring(10, 12); //当日分配的总时间段数
				time_block_numberinit = StringUtil.int16to10ByParam(time_block_number1, 1);
				time_block_number = String.valueOf(time_block_numberinit);
				//这里涉及N个时间段的事件检测点和对应的费率，报文长度不确定。
				List<String> list_3 = new ArrayList<String>();//每个时间段的截止时间点
				List<String> list_4 = new ArrayList<String>();//每时间段的费率
				for(int i=0;i<time_block_numberinit;i++){
					String deadline_time = chargerMsgBody.substring( 12+(18*i),26+(18*i) );
					list_3.add(deadline_time);
					String time_rate = chargerMsgBody.substring( 26+(18*i),30+(18*i) );
					list_4.add(time_rate);
				}
				map.put("charge_mode", charge_mode);
				map.put("rate", rate);
				map.put("time_block_number", time_block_number);

				String key_4 = map.get("chargerId")+"0"+map.get("portNo")+"_time_block_1";
				String key_5 = map.get("chargerId")+"0"+map.get("portNo")+"_time_block_2";
				String key_6 = map.get("chargerId")+"0"+map.get("portNo")+"_time_block_3";
				RedisClient.putMap(key_4, map);
				RedisClient.putList(key_5, list_3);
				RedisClient.putList(key_6, list_4);
				break;
			case "05":		//白名单	0x05
				String operation_type = chargerMsgBody.substring(4, 6); //操作方法
				String whitelist_number1 = chargerMsgBody.substring(6, 8); //此次下发白名单卡号的总数量
				int whitelist_number_init = StringUtil.int16to10ByParam(whitelist_number1, 1);
				String whitelist_number = String.valueOf(whitelist_number_init);
				//这里涉及N个白名单卡号，报文长度不确定。
				List<String> list_5 = new ArrayList<String>();//白名单卡号
				for(int i=0;i<whitelist_number_init;i++){
					String user_pay_card = chargerMsgBody.substring( 8+(20*i),28+(20*i) );
					list_5.add(user_pay_card);
				}
				map.put("operation_type", operation_type);
				map.put("whitelist_number", whitelist_number);

				String key_7 = map.get("chargerId")+"0"+map.get("portNo")+"white_list1";
				String key_8 = map.get("chargerId")+"0"+map.get("portNo")+"white_list2";
				RedisClient.putMap(key_7, map);
				RedisClient.putList(key_8, list_5);
				break;
			case "06":		//当前用户卡号 0x06
				String user_pay_card = chargerMsgBody.substring(4, 24); //用户卡号
				map.put("user_pay_card", user_pay_card);
				break;
			case "07":		//电桩当前状态 0x07
				String charge_status = chargerMsgBody.substring(4, 6);
				map.put("charge_status", charge_status);
				break;
			case "08":		//所在地电桩的标识
				String serial_no1 = chargerMsgBody.substring(4, 6);
				int serial_no_init = StringUtil.int16to10ByParam(serial_no1, 1);
				String serial_no = String.valueOf(serial_no_init);

				map.put("serial_no", serial_no);
				break;
			default:
				break;
			}
		}

		return map;
	}

	@Override
	public Map<String, String> requestPayByCard(Map<String, String> map) {
		
		return null;
	}

	@Override
	public Map<String, String> uploadHeart(Map<String, String> map) {
		//报文头解析
		map = getEv3c2MsgHeaderByMiddleBegin(map);
		// 无报文体解析
		return map; 
	}

	@Override
	//6.9电桩状态突变
	public Map<String, String> uploadChange(Map<String, String> map) {
		// 报文头解析
		map = getEv3c2MsgHeaderByMiddleBegin(map);
		// 报文体解析
		String chargerMsgBody = map.get("chargerMsgBody");
		
		String user_pay_card="";//用户卡号
		String start_type="";   //开启方式
		String oms_msg_charge_jrnl="";//原电桩开启充电流水号
		String offline_balance_start="";//充电卡余额
		String offline_is_pay="";     //是否有效
		String error_code="";         //故障码
		String parking_car_status="";     //停车位状态--车位
		String parking_status="";         //停车位状态--状态
		String stop_charging_reason="";    //停止原因
		
		String charge_status = chargerMsgBody.substring(0, 2); //一级状态类型
		map.put("charge_status", charge_status);
		switch (charge_status) {
		case "01":                                             //空闭（0x01）
			break;
		case "02":                                             //预约（0x02）
			user_pay_card = chargerMsgBody.substring(2, 22);
			map.put("user_pay_card", user_pay_card);
			break; 
		case "03":                                             //开启充电（0x03）
			start_type = chargerMsgBody.substring(2, 4);
			user_pay_card = chargerMsgBody.substring(4, 24);
			map.put("start_type", start_type);
			map.put("user_pay_card", user_pay_card);
			break;
		case "04":                                             //停止充电（0x04）
            user_pay_card = chargerMsgBody.substring(2, 22);
            stop_charging_reason = chargerMsgBody.substring(22, 24);
			oms_msg_charge_jrnl = chargerMsgBody.substring(24, 42);
			map.put("user_pay_card", user_pay_card);
			map.put("stop_charging_reason", stop_charging_reason);
			map.put("oms_msg_charge_jrnl", oms_msg_charge_jrnl);
			break;
		case "05":                                             //刷卡（0x05）
			user_pay_card = chargerMsgBody.substring(2, 22);
			String offline_balance_start1 = chargerMsgBody.substring(22, 30);
			float  offline_balance_start_init = StringUtil.float16to10ByParamDesc(offline_balance_start1, 1);
			offline_balance_start = String.valueOf(offline_balance_start_init);
			offline_is_pay=chargerMsgBody.substring(30, 32);
			map.put("user_pay_card", user_pay_card);			
			map.put("offline_balance_start", offline_balance_start);
			map.put("offline_is_pay", offline_is_pay);
			break;
		case "06":                                             //电桩故障（0x06）
			error_code = chargerMsgBody.substring(2, 8);
			map.put("error_code", error_code);
			break;
		case "07":                                             //停车位状态(0x07)
			parking_car_status = chargerMsgBody.substring(2, 4);
			parking_status = chargerMsgBody.substring(4, 6);
			map.put("parking_car_status", parking_car_status);
			map.put("parking_status", parking_status);
			break;

		default:
			break;
		}
		return map;  
	}

	@Override
	public Map<String, String> uploadFirmwareStatus(Map<String, String> map) {
		
		return null;
	}

	@Override
	//6.11帐单信息上送
	public Map<String, String> uploadBill(Map<String, String> map) {
		// 报文头解析
		map = getEv3c2MsgHeaderByMiddleBegin(map);
		// 报文体解析
		String chargerMsgBody = map.get("chargerMsgBody");
		
		String user_pay_card = chargerMsgBody.substring(0, 20);               //用户卡号

		String reservation_fee1 = chargerMsgBody.substring(20, 28);           //本次预约金额BIN码
		float  reservation_fee2 = StringUtil.float16to10ByParamDesc(reservation_fee1, 1);
		String reservation_fee = String.valueOf(reservation_fee2);

		String charge_payment1 = chargerMsgBody.substring(28, 36);            //本次充电金额BIN码
		float  charge_payment1_init = StringUtil.float16to10ByParamDesc(charge_payment1, 1);
		String charging_fee = String.valueOf(charge_payment1_init);

		String service_fee1 = chargerMsgBody.substring(36, 40);              //*服务费金额BIN码
		float service_fee2 = StringUtil.float16to10ByParamDesc(service_fee1, 1);
		String service_fee = String.valueOf(service_fee2);

		String start_type = chargerMsgBody.substring(40, 42);                    //开启方式
		String oms_msg_charge_jrnl = chargerMsgBody.substring(42, 60);           //原服务器/电桩 开启充电流水号
		String start_time = chargerMsgBody.substring(60, 74);                    //充电开始时间
		String end_time = chargerMsgBody.substring(74, 88);                    //充电结束时间
		String start_em1 = chargerMsgBody.substring(88,96);                   //充电前电表读数BIN码
		float  start_em1_init = StringUtil.float16to10ByParamDesc(start_em1, 1);
		String start_em = String.valueOf(start_em1_init);
		String end_em1 = chargerMsgBody.substring(96, 104);                   //充电后电表读数BIN码
		float  end_em_init = StringUtil.float16to10ByParamDesc(end_em1, 1);
		String end_em = String.valueOf(end_em_init);

		String this_reading1 = chargerMsgBody.substring(104, 112);                   //本次充电电量BIN码
		float  this_reading_init = StringUtil.float16to10ByParamDesc(this_reading1, 1);
		String this_reading = String.valueOf(this_reading_init);

		String offline_balance_end1 = chargerMsgBody.substring(112, 120);                   //充电后卡余额BIN码
		float  offline_balance_end_init = StringUtil.float16to10ByParamDesc(offline_balance_end1, 1);
		String offline_balance_end = String.valueOf(offline_balance_end_init);

		String offline_is_pay1 = chargerMsgBody.substring(120, 122);                   //是否线下支付BIN码
		int  offline_is_pay_init = StringUtil.int16to10ByParam(offline_is_pay1, 1);
		String offline_is_pay = String.valueOf(offline_is_pay_init); 
		String vin = chargerMsgBody.substring(122, 156);                               //车辆识别码（VIN）

		Integer noOfChargingTime = Integer.valueOf(chargerMsgBody.substring(156, 158));
		String[] listCharingStartTime = new String[noOfChargingTime];
		String[] listCharingEndTime = new String[noOfChargingTime];
		String[] listCharingAmount = new String[noOfChargingTime];

		int startIndex = 158;
		int endIndex = startIndex;
		for(int i = 0; i< noOfChargingTime; i++)
		{
			endIndex += 14;
			listCharingStartTime[i] = chargerMsgBody.substring(startIndex, endIndex);
			startIndex = endIndex;
			endIndex += 14;
			listCharingEndTime[i] = chargerMsgBody.substring(startIndex, endIndex);
			startIndex = endIndex;
			endIndex += 8;
			listCharingAmount[i] = String.valueOf(StringUtil.float16to10ByParamDesc(chargerMsgBody.substring(startIndex, endIndex), 1));
			startIndex = endIndex;
		}


		map.put("user_pay_card", user_pay_card);
		map.put("reservation_fee", reservation_fee);
		map.put("charging_fee", charging_fee);
		map.put("service_fee",service_fee);

		map.put("start_type", start_type);
		map.put("oms_msg_charge_jrnl", oms_msg_charge_jrnl);
		map.put("start_time", start_time);
		map.put("end_time", end_time);
		map.put("start_em", start_em);
		map.put("end_em", end_em);
		map.put("this_reading", this_reading);
		map.put("offline_balance_end", offline_balance_end);
		map.put("offline_is_pay", "0");//固定为未支付
		map.put("vin", vin);

		map.put("listCharingStartTime", StringUtils.join(listCharingAmount, ","));
		map.put("listCharingEndTime", StringUtils.join(listCharingEndTime, ","));
		map.put("listCharingAmount", StringUtils.join(listCharingAmount, ","));
		
		return map;
	}

	@Override
	//充电状态上送
	public Map<String, String> uploadChargeData(Map<String, String> map) {
		// 报文头解析
		map = getEv3c2MsgHeaderByMiddleBegin(map);
		// 报文体解析
		String chargerMsgBody = map.get("chargerMsgBody");                           
		String oms_msg_charge_jrnl = chargerMsgBody.substring(0, 18);               //原服务器/电桩 开启充电流水号
		String charger_kwh1 = chargerMsgBody.substring(18,26);                      //当前已用电量BIN码
		float charger_kwh_init = StringUtil.float16to10ByParamDesc(charger_kwh1, 100);
		String charger_kwh = String.valueOf(charger_kwh_init);
		String charger_time1 = chargerMsgBody.substring(26,34);                      //当前总充电时间(分)BIN码
		float  charger_time_init = StringUtil.float16to10ByParamDesc(charger_time1, 1);
		String charger_time = String.valueOf(charger_time_init);
		String charger_fee1 = chargerMsgBody.substring(34,42);                      //当前已使用充电电费总金额BIN码
		float  charger_fee_init = StringUtil.float16to10ByParamDesc(charger_fee1, 100);
		String charger_fee = String.valueOf(charger_fee_init);
		String char_bill1 = chargerMsgBody.substring(42,50);                      //当前已使用服务费总金额BIN码
		float  char_bill_init = StringUtil.float16to10ByParamDesc(char_bill1, 100);
		String char_bill = String.valueOf(char_bill_init);
		String charger_v1 = chargerMsgBody.substring(50,56);                      //当前充电电压BIN码
		float  charger_v_init = StringUtil.float16to10ByParamDesc(charger_v1, 100);
		String charger_v = String.valueOf(charger_v_init);
		String charger_i1 = chargerMsgBody.substring(56,62);                      //当充电电流BIN码
		float  charger_i_init = StringUtil.float16to10ByParamDesc(charger_i1, 100);
		String charger_i = String.valueOf(charger_i_init);
		String charger_p1 = chargerMsgBody.substring(62,68);                      //当前输出功率BIN码
		float  charger_p_init = StringUtil.float16to10ByParamDesc(charger_p1, 100);
		String charger_p = String.valueOf(charger_p_init);
		String soc1 = chargerMsgBody.substring(68,70);                      //当前荷电状态SOC BIN码
		int  soc_init = StringUtil.int16to10ByParam(soc1, 1);
		String soc = String.valueOf(soc_init);
		String remaining_time1 = chargerMsgBody.substring(70,74);                      //估算剩余充电时间 BIN码
		float  remaining_time_init = StringUtil.float16to10ByParamDesc(remaining_time1, 1);
		String remaining_time = String.valueOf(remaining_time_init);
		
		map.put("oms_msg_charge_jrnl", oms_msg_charge_jrnl);
		map.put("charger_kwh", charger_kwh);
		map.put("charger_time", charger_time);
		map.put("charger_fee", charger_fee);
		map.put("char_bill", char_bill);
		map.put("charger_v", charger_v);
		map.put("charger_i", charger_i);
		map.put("charger_p", charger_p);
		map.put("soc", soc);
		map.put("remaining_time", remaining_time);

		return map;
	}

	//电池信息解析
	@Override
	public Map<String, String> uploadBatteryData(Map<String, String> map)
	{
		// 报文头解析
		map = getEv3c2MsgHeaderByMiddleBegin(map);
		// 报文体解析
		String chargerMsgBody = map.get("chargerMsgBody");

		int index = 0;
		String serialNumber = chargerMsgBody.substring(index, index += 9 * 2);               //原服务器/电桩 开启充电流水号

		String charger_v_demand1 = chargerMsgBody.substring(index, index += 2 * 2);                    //充电电压需求BIN码
		float charger_v_demand_init = StringUtil.float16to10ByParamDesc(charger_v_demand1, 10);
		String charger_v_demand = String.valueOf(charger_v_demand_init);

		String charger_i_demand1 = chargerMsgBody.substring(index, index += 2 * 2);                    //充电电流需求BIN码
		float charger_i_demand_init = StringUtil.convertBinToIntWithNegative(charger_i_demand1, 10);
		String charger_i_demand = String.valueOf(charger_i_demand_init);

		String charger_v_measure1 = chargerMsgBody.substring(index, index += 2 * 2);                    //充电电压测量BIN码
		float charger_v_measure_init = StringUtil.float16to10ByParamDesc(charger_v_measure1, 10);
		String charger_v_measure = String.valueOf(charger_v_measure_init);

		String charger_i_measure1 = chargerMsgBody.substring(index, index += 2 * 2);                    //充电电流测量BIN码
		float charger_i_measure_init = StringUtil.convertBinToIntWithNegative(charger_i_measure1, 10);
		String charger_i_measure = String.valueOf(charger_i_measure_init);

		String highest_battery_Groupnumber1 = chargerMsgBody.substring(index, index += 2 * 2);                //最高单体电池及其组号
		String highest_battery_groupnumber_voltage = String.valueOf(StringUtil.convertBinToIntByBit(highest_battery_Groupnumber1, 100, 1, 12));
		String highest_battery_groupnumber = String.valueOf(StringUtil.convertBinToIntByBit(highest_battery_Groupnumber1, 1, 13, 16));

		String charger_state1 = chargerMsgBody.substring(index, index += 1 * 2);                          //当前荷电状态
		float charger_state_init = StringUtil.float16to10ByParamDesc(charger_state1, 100);
		String charger_state = String.valueOf(charger_state_init);

		String charger_time_left1 = chargerMsgBody.substring(index, index += 2 * 2);                          //估计充电剩余时间BIN码
		float charger_time_leftinit = StringUtil.float16to10ByParamDesc(charger_time_left1, 1);
		String charger_time_left_min = String.valueOf(charger_time_leftinit);

		String highest_battery_number1 = chargerMsgBody.substring(index, index += 1 * 2);              //最高单体电池电压所在编号
		int highest_battery_numberinit = StringUtil.int16to10ByParam(highest_battery_number1, 1);
		String highest_battery_number = String.valueOf(highest_battery_numberinit);

		String battery_temperature_max1 = chargerMsgBody.substring(index, index += 1 * 2);             //最高动力电池温度
		float battery_temperature_maxinit = StringUtil.convertBinToIntWithNegative(battery_temperature_max1, 1);
		String battery_temperature_max = String.valueOf(battery_temperature_maxinit);

		String temperature_max_number1 = chargerMsgBody.substring(index, index += 1 * 2);                     //最高电池温度检测点编号
		int temperature_max_numberint = StringUtil.int16to10ByParam(temperature_max_number1, 1);
		String temperature_max_number = String.valueOf(temperature_max_numberint);

		String battery_temperature_min1 = chargerMsgBody.substring(index, index += 1 * 2);              //最低动力电池温度
		float battery_temperature_mininit = StringUtil.convertBinToIntWithNegative(battery_temperature_min1, 1);
		String battery_temperature_min = String.valueOf(battery_temperature_mininit);

		String temperature_min_number1 = chargerMsgBody.substring(index, index += 1 * 2);                           //最低电池温度检测点编号
		int temperature_min_numberint = StringUtil.int16to10ByParam(temperature_min_number1, 1);
		String temperature_min_number = String.valueOf(temperature_min_numberint);

		String battery_state1_bin = chargerMsgBody.substring(index, index += 1 * 2);                        //动力电池状态1
		int battery_state1_init = StringUtil.int16to10ByParam(battery_state1_bin, 1);
		String battery_state1 = String.valueOf(battery_state1_init);

		String battery_state2_bin = chargerMsgBody.substring(index, index += 1 * 2);                            //动力电池状态2
		int battery_state2_init = StringUtil.int16to10ByParam(battery_state2_bin, 1);
		String battery_state2 = String.valueOf(battery_state2_init);

		String reservation_bin = chargerMsgBody.substring(index, index += 6 * 2);                                //保留
		float reservation_init = StringUtil.float16to10ByParamDesc(reservation_bin, 1);
		String reservation = String.valueOf(reservation_init);

		String battery_count_bin = chargerMsgBody.substring(index, index += 2 * 2); //电池单体个数
		long battery_count_int = StringUtil.int16to10ByParamDesc(battery_count_bin);
		int battery_count_begin = index;
		List<BatteryInfoUploadVO.BatteryVoltage> list_1 = new ArrayList<>();
		for (int i = 0; i < battery_count_int; i++)
		{
			String battery_info = chargerMsgBody.substring(battery_count_begin + i * 4, battery_count_begin + (i + 1) * 4);
			BatteryInfoUploadVO.BatteryVoltage info = new BatteryInfoUploadVO.BatteryVoltage();
			info.setVoltage(String.valueOf(StringUtil.convertBinToIntByBit(battery_info, 100, 1, 12)));
			info.setNumber(String.valueOf(StringUtil.convertBinToIntByBit(highest_battery_Groupnumber1, 1, 13, 16)));

//			String battery_no_v_temp_float = StringUtil.float10to16ByParamDesc(battery_no_v_temp, 100, 4);
			list_1.add(info);
		}

		index += battery_count_int * 2 * 2;

		String temperature_sample_no_bin = chargerMsgBody.substring(index, index += 2 * 2);;
		long temperature_sample_no_int = StringUtil.int16to10ByParamDesc(temperature_sample_no_bin);
		int temperature_sample_begin = index;
		List<String> list_2 = new ArrayList<>();
		for (int i = 0; i < temperature_sample_no_int; i++)
		{
			String temperature_temp = chargerMsgBody.substring(temperature_sample_begin + i * 2, temperature_sample_begin + (i + 1) * 2);
			int temperature_int = StringUtil.int16to10ByParam(temperature_temp, 100);
			list_2.add(String.valueOf(temperature_int));
		}
		map.put("beginChargeSerialNumber", serialNumber);
		map.put("charger_v_demand", charger_v_demand);
		map.put("charger_i_demand", charger_i_demand);
		map.put("charger_v_measure", charger_v_measure);
		map.put("charger_i_measure", charger_i_measure);
		map.put("charger_state", charger_state);
		map.put("charger_time_left_minute", charger_time_left_min);
		map.put("highest_battery_number", highest_battery_number);
		map.put("battery_temperature_max", battery_temperature_max);
		map.put("temperature_max_number", temperature_max_number);
		map.put("battery_temperature_min", battery_temperature_min);
		map.put("highest_battery_groupnumber", highest_battery_groupnumber);
		map.put("highest_battery_groupnumber_voltage", highest_battery_groupnumber_voltage);
		map.put("temperature_min_number", temperature_min_number);
		map.put("reservation", reservation);
		map.put("battery_state1", battery_state1);
		map.put("battery_state2", battery_state2);
		map.put("battery_no", String.valueOf(battery_count_int));
		map.put("temperature_sample_no", String.valueOf(temperature_sample_no_int));
//		String key_1 = map.get("chargerId") + "0" + map.get("portNo") + "_battery_1";
//		String key_2 = map.get("chargerId") + "0" + map.get("portNo") + "_battery_2";
//		String key_3 = map.get("chargerId") + "0" + map.get("portNo") + "_battery_3";

		String key = serialNumber + "_batteryInfo";
		BatteryInfoUploadVO vo = new BatteryInfoUploadVO();
		vo.setMainInfo(map);
		vo.setBatteryVoltages(list_1);
		vo.setBatteryTemperatures(list_2);
		Jedis jedis = RedisClient.getConnect();
		jedis.lpush(key, JSON.toJSONString(vo));
		jedis.close();
//		RedisClient.putMap(key_1, map);
//		RedisClient.putList(key_2, list_1);
//		RedisClient.putList(key_3, list_2);
		return map;
	}

	@Override
	public Map<String, String> summonReturnUploadTelemetry(Map<String, String> map) {
		
		return null;
	}

	@Override
	public Map<String, String> summonReturnUploadTelesignal(Map<String, String> map) {
		
		return null;
	}

	@Override
	public Map<String, String> summonReturnUploadPulse(Map<String, String> map) {
		
		return null;
	}

	@Override
	public Map<String, String> chargerUnRegister(Map<String, String> map) {
		map = getEv3c2MsgHeaderByMiddleBegin(map);
		// 报文体解析
		String chargerMsgBody = map.get("chargerMsgBody");
		String unregister_reason = chargerMsgBody.substring(0, 2); //注销原因		
		map.put("unregister_reason", unregister_reason);		
		return map;
	}

	@Override
	public Map<String, String> chargerLogin(Map<String, String> map) {
		//报文头解析
		map = getEv3c2MsgHeaderByMiddleBegin(map);
		// 报文体解析
		String chargerMsgBody = map.get("chargerMsgBody");
		String fac_login_name = chargerMsgBody.substring(0, 8); //注册账号  00005024  厂商表中检查
		String fac_password = chargerMsgBody.substring(8, 16); //注册密码      21968502    
		String coordinate_x =  chargerMsgBody.substring(16, 24); //*GPS经度	BIN码
		String coordinate_y =  chargerMsgBody.substring(24, 32); //*GPS纬度	BIN码
		String software_version =  chargerMsgBody.substring(24, 32); //*GPS纬度	BIN码
		String protocol_version = map.get("protocol_version"); //*GPS纬度	BIN码
		map.put("fac_login_name", fac_login_name);
		map.put("fac_password", fac_password);
		map.put("software_version", software_version);
		map.put("protocol_version", protocol_version);
		return map;  
	}

	@Override
	public Map<String, String> chargerLogout(Map<String, String> map) {
		//报文头解析
		map = getEv3c2MsgHeaderByMiddleBegin(map);
		// 无报文体解析
		return map;  
	}



}
